﻿using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Web.UI;
using System.Web.SessionState;
using System.Text.RegularExpressions;

public class BetterUrlRewriter : IHttpHandler, IRequiresSessionState
{
    const string ORIGINAL_PATHINFO = "UrlRewriterOriginalPathInfo";
    const string ORIGINAL_QUERIES = "UrlRewriterOriginalQueries";

    public void ProcessRequest(HttpContext context)
    {
        // Check to see if the specified HTML file actual exists and serve it if so..        
        String strReqPath = context.Server.MapPath(context.Request.AppRelativeCurrentExecutionFilePath);
        if (File.Exists(strReqPath))
        {
            context.Response.WriteFile(strReqPath);
            context.Response.End();
            return;
        }

        // Record the original request PathInfo and QueryString information to handle graceful postbacks        
        context.Items[ORIGINAL_PATHINFO] = context.Request.PathInfo;
        context.Items[ORIGINAL_QUERIES] = context.Request.QueryString.ToString();

        // Map the friendly URL to the back-end one..        
        String strVirtualPath = "";
        String strQueryString = "";
        MapFriendlyUrl(context, out strVirtualPath, out strQueryString);
        if (strVirtualPath.Length > 0)
        {
            foreach (string strOriginalQuery in context.Request.QueryString.Keys)
            {
                // To ensure that any query strings passed in the original request are preserved, we append these                 
                // to the new query string now, taking care not to add any keys which have been rewritten during the handler..                
                if (strQueryString.ToLower().IndexOf(strOriginalQuery.ToLower() + "=") < 0)
                {
                    strQueryString += string.Format("{0}{1}={2}", ((strQueryString.Length > 0) ? "&" : ""), strOriginalQuery, context.Request.QueryString[strOriginalQuery]);
                }
            }

            // Apply the required query strings to the request            
            context.RewritePath(context.Request.Path, string.Empty, strQueryString);
            // Now get a page handler for the ASPX page required, using this context.              
            Page aspxHandler = (Page)PageParser.GetCompiledPageInstance(strVirtualPath, context.Server.MapPath(strVirtualPath), context);
            // Execute the handler..            
            aspxHandler.PreRenderComplete += new EventHandler(AspxPage_PreRenderComplete);
            aspxHandler.ProcessRequest(context);
        }
        else
        {
            // No mapping was found - emit a 404 response.             
            context.Response.StatusCode = 404;
            context.Response.ContentType = "text/plain";
            context.Response.Write("Page Not Found");
            context.Response.End();
        }
    }

    void MapFriendlyUrl(HttpContext context, out String strVirtualPath, out String strQueryString)
    {
        strVirtualPath = ""; strQueryString = "";

        // TODO: This routine should examine the context.Request properties and implement        
        //       an appropriate mapping system.        
        //        
        //       Set strVirtualPath to the virtual path of the target aspx page.        
        //       Set strQueryString to any query strings required for the page.         

        //try
        //{
        //    string categoryPattern = @"^/dien-thoai/([a-zA-Z_0-9-]+)-([0-9]+).html$";
        //    Regex myRegex = new Regex(categoryPattern);
        //    Match m = myRegex.Match(context.Request.Path.ToString());

        //    if (m.Success)
        //    {
        //        string[] url = context.Request.Path.Split('-');
        //        string[] endR = (url[url.Length - 1]).Split('.');
        //        int id = Convert.ToInt32(endR[0]);
        //        strVirtualPath = "~/Rewrite.aspx";
        //        strQueryString = "ProductID=" + id;
        //    }
        //}
        //catch (System.Exception ex)
        //{
        //    throw ex;
        //}


        if (context.Request.Path.Contains(".html"))
        {
            // Example hard coded mapping of "FriendlyPage.html" to "UnfriendlyPage.aspx"             

            strVirtualPath = context.Request.Path.Replace(".html", ".aspx");
            //strQueryString = "FirstQuery=1&SecondQuery=2";
        }
    }

    void AspxPage_PreRenderComplete(object sender, EventArgs e)
    {
        // We need to rewrite the path replacing the original tail and query strings..        
        // This happens AFTER the page has been loaded and setup but has the effect of ensuring        
        // postbacks to the page retain the original un-rewritten pages URL and queries.         

        HttpContext.Current.RewritePath(HttpContext.Current.Request.Path,
        HttpContext.Current.Items[ORIGINAL_PATHINFO].ToString(),
        HttpContext.Current.Items[ORIGINAL_QUERIES].ToString());
    }

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }
}
